<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js"><span id='global-property-'>/**
</span> * @ignore
 * manage a list of single-select options
 * @author yiminghe@gmail.com
 */
KISSY.add(&quot;menubutton/select&quot;, function (S, Node, MenuButton, Menu, Option, undefined) {
    function getSelectedItem(self) {
        var menu = self.get(&quot;menu&quot;),
            cs = menu.children || menu.get &amp;&amp; menu.get(&quot;children&quot;) || [],
            value = self.get(&quot;value&quot;),
            c,
            i;
        for (i = 0; i &lt; cs.length; i++) {
            c = cs[i];
            if (getItemValue(c) == value) {
                return c;
            }
        }
        return null;
    }

    // c: Option
    // c.get(&quot;value&quot;)
    // c: Object
    // c.value
    function getItemValue(c) {
        var v;
        if (c) {
            if (c.get) {
                if ((v = c.get(&quot;value&quot;)) === undefined) {
                    v = c.get(&quot;textContent&quot;) || c.get(&quot;content&quot;);
                }
            } else {
                if ((v = c.value) === undefined) {
                    v = c.textContent || c.content;
                }
            }
        }
        return v;
    }

    function deSelectAllExcept(self) {
        var menu = self.get(&quot;menu&quot;),
            value = self.get(&quot;value&quot;),
            cs = menu &amp;&amp; menu.get &amp;&amp; menu.get(&quot;children&quot;);
        S.each(cs, function (c) {
            if (c &amp;&amp; c.set) {
                c.set(&quot;selected&quot;, getItemValue(c) == value)
            }
        });
    }


    // different from menubutton by highlighting the currently selected option on open menu.
    function _handleMenuShow(e) {
        var self = this,
            selectedItem = getSelectedItem(self),
            m = self.get(&quot;menu&quot;);
        if (e.target === m) {
            var item = selectedItem || m.getChildAt(0);
            if (item) {
                item.set('highlighted', true);
            }
            // 初始化选中
            if (selectedItem) {
                selectedItem.set(&quot;selected&quot;, true);
            }
        }
    }

    function _updateCaption(self) {
        var item = getSelectedItem(self),
            textContent = item &amp;&amp; ( item.textContent || item.get &amp;&amp; item.get(&quot;textContent&quot;)),
            content = item &amp;&amp; (item.content || item.get &amp;&amp; item.get('content'));
        // 可能设置到 select content 的内容并不和 menuitem 的内容完全一致
        self.set(&quot;content&quot;, textContent || content || self.get(&quot;defaultCaption&quot;));
    }


    /*
     Handle click on drop down menu.
     Set selected menu item as current selectedItem and hide drop down menu.
     Protected, should only be overridden by subclasses.
     */
    function handleMenuClick(e) {
        var self = this,
            target = e.target;
        if (target.isMenuItem) {
            var newValue = getItemValue(target),
                oldValue = self.get(&quot;value&quot;);
            self.set(&quot;value&quot;, newValue);
            if (newValue != oldValue) {
                self.fire(&quot;change&quot;, {
                    prevVal: oldValue,
                    newVal: newValue
                });
            }
        }
    }


<span id='KISSY-MenuButton-Select'>    /**
</span>     * Select component which supports single selection from a drop down menu
     * with semantics similar to native HTML select.
     * xclass: 'select'.
     * @class KISSY.MenuButton.Select
     * @extends KISSY.MenuButton
     */
    var Select = MenuButton.extend({
            bindUI: function () {
                this.on(&quot;click&quot;, handleMenuClick, this);
                this.on('show', _handleMenuShow, this);
            },

<span id='KISSY-MenuButton-Select-method-removeItems'>            /**
</span>             * Removes all menu items from current select, and set selectedItem to null.
             *
             */
            removeItems: function () {
                var self = this;
                self.callSuper.apply(self,arguments);
                self.set(&quot;value&quot;, null);
            },

<span id='KISSY-MenuButton-Select-method-removeItem'>            /**
</span>             * Remove specified item from current select.
             * If specified item is selectedItem, then set selectedItem to null.
             * @param c {KISSY.MenuButton.Option} Existing menu item.
             * @param [destroy=true] {Boolean} Whether destroy removed menu item.
             */
            removeItem: function (c,destroy) {
                var self = this;
                self.callSuper(c,destroy);
                if (c.get(&quot;value&quot;) == self.get(&quot;value&quot;)) {
                    self.set(&quot;value&quot;, null);
                }
            },

            _onSetValue: function () {
                var self = this;
                deSelectAllExcept(self);
                _updateCaption(self);
            },

            '_onSetDefaultCaption': function () {
                _updateCaption(this);
            }
        },
        {
            ATTRS: {

<span id='KISSY-MenuButton-Select-property-value'>                /**
</span>                 * Get current select 's value.
                 */
                value: {
                },

<span id='KISSY-MenuButton-Select-property-defaultCaption'>                /**
</span>                 * Default caption to be shown when no option is selected.
                 * @type {String}
                 */
                defaultCaption: {
                    value: &quot;&quot;
                },

                collapseOnClick: {
                    value: true
                }
            },

<span id='KISSY-MenuButton-Select-method-decorate'>            /**
</span>             * Generate a select component from native select element.
             * @param {HTMLElement} element Native html select element.
             * @param {Object} cfg Extra configuration for current select component.
             * @member KISSY.MenuButton.Select
             */
            decorate: function (element, cfg) {
                element = S.one(element);
                cfg = cfg || {};
                cfg.elBefore = element;

                var name,
                    allItems = [],
                    select,
                    selectedItem = null,
                    curValue = element.val(),
                    options = element.all(&quot;option&quot;);

                options.each(function (option) {
                    var item = {
                        xclass: 'option',
                        content: option.text(),
                        elCls: option.attr(&quot;class&quot;),
                        value: option.val()
                    };
                    if (curValue == option.val()) {
                        selectedItem = {
                            content: item.content,
                            value: item.value
                        };
                    }
                    allItems.push(item);
                });

                S.mix(cfg, {
                    menu: S.mix({
                        children: allItems
                    }, cfg.menuCfg)
                });

                delete cfg.menuCfg;

                select = new Select(S.mix(cfg, selectedItem)).render();

                if (name = element.attr(&quot;name&quot;)) {
                    var input = new Node(&quot;&lt;input&quot; +
                        &quot; type='hidden'&quot; +
                        &quot; name='&quot; + name
                        + &quot;' value='&quot; + curValue + &quot;'&gt;&quot;)
                        .insertBefore(element, undefined);

                    select.on(&quot;afterValueChange&quot;, function (e) {
                        input.val(e.newVal || &quot;&quot;);
                    });
                }

                element.remove();
                return select;
            },
            xclass: 'select'

        });

    return Select;

}, {
    requires: ['node', './control', 'menu', './option']
});

/*
  TODO
   how to emulate multiple ?
 */</pre>
</body>
</html>
